import DivideType from "./DivideType.js";
class ObjectParser {
    constructor({ DivideType: inputDivideType } = {}) {
        this.DivideType = { ...DivideType, ...inputDivideType };
    }
    parse(Input, Template) {
        return this.Splitter(this.PreDecode(Input), Template, {});
    }
    PreDecode(input) {
        return input;
    }

    // Entity 是传入的实体
    Splitter(Entity, Template, collection) {
        Template = this.Entries(Template);
        Template.forEach(([Selector, divider]) => {
            const { multi, callback } = this.Divide(divider);
            const [_, selector, hasKey, key] =
                Selector.match(/([^@]*)(?:(@)(.*))?/);
            const target = this.Select(Entity, selector, { multi });

            // console.log(Entity, `==${selector}==>`, target, "|");
            const result = callback.call(
                this,
                target,
                divider,
                // 有 key 标记时就会获得继承性
                hasKey === "@" ? {} : collection
            );
            if (hasKey === "@") {
                // 这里不适合使用 selector 作为默认的 key
                // 深度解构 value 到浅层的 结果对象中时，路径会被保留
                // demo: { name:{ name2:{name3:''} }}
                collection[key || selector] = result;
            }
        });
        return collection;
    }
    Entries(Entity) {
        if (Entity instanceof Array) {
            return Entity;
        } else {
            return Object.entries(Entity);
        }
    }

    type(any) {
        return Object.prototype.toString
            .call(any)
            .match(/(?<=\[object\s+)\S+?(?=\])/)[0];
    }
    // options 为从系统中发出的设置，而不是用户发出的设置
    Select(fatherElement, selector, { multi }) {
        if (selector !== null && selector !== undefined) {
            // if (multi) {
            //     return Object.entries(fatherElement).reduce(
            //         (col, [key, value]) => {
            //             if (new RegExp(selector).test(key)) {
            //                 col[key] = value;
            //             }
            //             return col;
            //         },
            //         {}
            //     );
            // } else {
            return fatherElement[selector];
            // }
        } else {
            return undefined;
        }
    }

    Divide(divider) {
        const type = this.type(divider);
        // console.log(type);
        return {
            multi: divider instanceof Array,
            callback: this.DivideType[type] || this.DivideType.default,
        };
    }
}
export default ObjectParser;
